/*
 * 项目名称:    wms-server-jeecg
 * 创建人员:    gongwenkai
 * 创建时间:    2023-09-26
 */
package org.jeecg.modules.flow.callback.outbound.task;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceipt;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceiptMaterial;
import org.jeecg.modules.business.doc.outbound.service.IWmsOutReceiptMaterialService;
import org.jeecg.modules.business.doc.outbound.service.IWmsOutReceiptService;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTask;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTaskMaterial;
import org.jeecg.modules.business.outbound.entity.vo.OutBoundTaskSaveVO;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskMaterialService;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskService;
import org.jeecg.modules.flow.callback.enums.DocumentStatusEnum;
import org.jeecg.modules.flow.callback.enums.OutboundStatusEnum;
import org.jeecg.modules.flow.callback.outbound.util.CommonOutboundUtil;
import org.jeecg.modules.flow.record.entity.WmsFlowRecord;
import org.jeecg.modules.flow.sys.common.BaseCustomBeanRun;
import org.jeecg.modules.flow.sys.entity.dto.BaseFlowDto;
import org.jeecg.modules.flow.sys.entity.dto.WorkFlowInfoDto;
import org.jeecg.modules.flow.sys.service.WorkFlowService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 出库任务出库 回调Bean 带自动创建出库单
 *
 * @author gongwenkai
 * @version 1.0.0
 * @since 2023-09-26
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class OutBoundTaskAutoOutBean<T> extends BaseCustomBeanRun<T> {

    private final IWmsOutReceiptTaskService wmsOutReceiptTaskService;

    private final IWmsOutReceiptTaskMaterialService wmsOutReceiptTaskMaterialService;

    private final WorkFlowService workFlowService;

    private final IWmsOutReceiptService wmsOutReceiptService;

    private final IWmsOutReceiptMaterialService wmsOutReceiptMaterialService;

    private final CommonOutboundUtil commonOutboundUtil;

    /**
     * 业务逻辑 出库任务提交
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void actureRun() {
        BaseFlowDto baseFlowDto = this.getBaseFlowDto();
        // 获取请求参数
        baseFlowDto.translateClass(JSONObject.class);
        JSONObject jsonData = (JSONObject) baseFlowDto.getData();
        Boolean fromReceiptOrderFlag = jsonData.getBoolean("fromReceiptOrderFlag");
        String taskId = baseFlowDto.getInfoId();
        if(fromReceiptOrderFlag!=null&&fromReceiptOrderFlag==true){
            //如果是从出库单流转过来的
            //判断并更新任务信息和状态
            //Boolean flag = updateTaskMaterial(jsonData.getString("receiptId"));
            Boolean completeFlag = commonOutboundUtil.checkOutTaskComplete(taskId);
            if(completeFlag){
                //如果已经全部出库，流转到下一个节点
                //更新任务的单据状态
                wmsOutReceiptTaskService.update(new LambdaUpdateWrapper<WmsOutReceiptTask>()
                    .set(WmsOutReceiptTask::getDocumentStatus,DocumentStatusEnum.COMPLETE.getCode())
                    .eq(WmsOutReceiptTask::getId,taskId)
                );
            }else{
                //如果没有全部出库，继续卡住
                baseFlowDto.setRunThenStop(true);
            }
        }else{
            autoCreateOrder(taskId);
            baseFlowDto.setRunThenStop(true);
        }
        // 当前前端调用业务需要你返回的
        baseFlowDto.setResult(Result.OK());
        // id是保存业务记录的id。用于生成业务流程信息记录
        baseFlowDto.setInfoId(taskId);
    }

    /**
     * 自动创建出库单
     */
    public void autoCreateOrder(String taskId) {

        WmsOutReceiptTask receiptTask = wmsOutReceiptTaskService.getById(taskId);
        List<WmsOutReceiptTaskMaterial> receiptTaskMaterialList = wmsOutReceiptTaskMaterialService.list(new LambdaUpdateWrapper<WmsOutReceiptTaskMaterial>()
                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, taskId)
        );
        WmsOutReceipt wmsOutReceipt = new WmsOutReceipt();
        wmsOutReceipt.setSysOrgCode(receiptTask.getSysOrgCode());
        wmsOutReceipt.setOrganization(receiptTask.getOrganization());
        wmsOutReceipt.setDocumentType(receiptTask.getDocumentType());
        wmsOutReceipt.setDocumentCode((String) FillRuleUtil.executeRule("ck_rule", null));
        wmsOutReceipt.setOwnerType(receiptTask.getOwnerType());
        wmsOutReceipt.setBusinessDate(null);
        wmsOutReceipt.setOwner(receiptTask.getOwner());
        wmsOutReceipt.setWarehouseDirection(receiptTask.getWarehouseDirection());
        wmsOutReceipt.setCustomer(receiptTask.getCustomer());
        wmsOutReceipt.setDocumentStatus(null);
        wmsOutReceipt.setWmsBasicWarehouseGroupId(receiptTask.getWmsBasicWarehouseGroupId());
        wmsOutReceipt.setRemark(null);
        wmsOutReceipt.setWarehouseKeeper(receiptTask.getWarehouseKeeper());
        wmsOutReceipt.setOutDate(new Date());
        wmsOutReceipt.setHasChild(1);
        wmsOutReceipt.setWmsOutReceiptTaskId(receiptTask.getId());

        List<WmsOutReceiptMaterial> wmsOutReceiptMaterialList = receiptTaskMaterialList.stream().map(o -> {
            WmsOutReceiptMaterial wmsOutReceiptMaterial = new WmsOutReceiptMaterial();
            wmsOutReceiptMaterial.setSysOrgCode(o.getSysOrgCode());
            wmsOutReceiptMaterial.setWmsBasicMaterialId(o.getWmsBasicMaterialId());
            wmsOutReceiptMaterial.setBatchCode(o.getBatchCode());
            wmsOutReceiptMaterial.setPayableQuantity(o.getPlanQuantity());
            wmsOutReceiptMaterial.setOutboundQuantity(o.getPlanQuantity());
            wmsOutReceiptMaterial.setWmsBasicWarehouseId(o.getWmsBasicWarehouseId());
            wmsOutReceiptMaterial.setWmsBasicWarehouseAreaId(o.getWmsBasicWarehouseAreaId());
            wmsOutReceiptMaterial.setWmsBasicWarehouseAreaLocationId(o.getWmsBasicWarehouseAreaLocationId());
            wmsOutReceiptMaterial.setAssistQuantity(Objects.isNull(o.getAssistQuantity()) ? null : o.getAssistQuantity());
            wmsOutReceiptMaterial.setSteelCoilNumber(o.getSteelCoilNumber());
            wmsOutReceiptMaterial.setOutsideDiameter(ObjectUtil.isEmpty(o.getOutsideDiameter()) ? null : o.getOutsideDiameter());
            wmsOutReceiptMaterial.setWidth(ObjectUtil.isEmpty(o.getWidth()) ? null : o.getWidth());
            wmsOutReceiptMaterial.setLength(ObjectUtil.isEmpty(o.getLength()) ? null : o.getLength());
            wmsOutReceiptMaterial.setThickness(ObjectUtil.isEmpty(o.getThickness()) ? null : o.getThickness());
            wmsOutReceiptMaterial.setShopSign(o.getShopSign());
            wmsOutReceiptMaterial.setAppearanceGrade(o.getAppearanceGrade());
            wmsOutReceiptMaterial.setIronLoss(o.getIronLoss());
            wmsOutReceiptMaterial.setMeasuredThickness(Objects.isNull(o.getMeasuredThickness()) ? null : o.getMeasuredThickness());
            wmsOutReceiptMaterial.setMeasuredIronLoss(o.getMeasuredIronLoss());
            wmsOutReceiptMaterial.setScore(o.getScore());
            wmsOutReceiptMaterial.setOriginalWeight(Objects.isNull(o.getOriginalWeight()) ? null : o.getOriginalWeight());
            wmsOutReceiptMaterial.setMeasuredWeight(Objects.isNull(o.getMeasuredWeight()) ? null : o.getMeasuredWeight());
            wmsOutReceiptMaterial.setVehicle(null);
            wmsOutReceiptMaterial.setSerialNumber(o.getSerialNumber());
            wmsOutReceiptMaterial.setSaleOrderNumber(o.getSaleOrderNumber());
            wmsOutReceiptMaterial.setSaleOrderLineNumber(o.getSaleOrderLineNumber());
            wmsOutReceiptMaterial.setProductNumber(o.getProductNumber());
            wmsOutReceiptMaterial.setProductLineNumber(o.getProductLineNumber());
            wmsOutReceiptMaterial.setUpstreamDocuments("出库任务");
            wmsOutReceiptMaterial.setUpstreamNumber(receiptTask.getDocumentCode());
            wmsOutReceiptMaterial.setUpstreamLineNumber(o.getUpstreamLineNumber());
            wmsOutReceiptMaterial.setOriginalSystemNumber(o.getOriginalSystemNumber());
            wmsOutReceiptMaterial.setOriginalSystemLineNumber(o.getOriginalSystemLineNumber());
            wmsOutReceiptMaterial.setGrossWeight(Objects.isNull(o.getGrossWeight()) ? null : o.getGrossWeight());
            wmsOutReceiptMaterial.setPayableQuantityAssist(o.getOutboundQuantityAssist());
            wmsOutReceiptMaterial.setOutboundQuantityAssist(o.getOutboundQuantityAssist());
            wmsOutReceiptMaterial.setWmsOutReceiptId(null);
            wmsOutReceiptMaterial.setWmsBasicUnitId(o.getWmsBasicUnitId());
            wmsOutReceiptMaterial.setMaterialCode(o.getMaterialCode());
            wmsOutReceiptMaterial.setSpecificationModel(o.getSpecificationModel());
            wmsOutReceiptMaterial.setIsMergeRoll(o.getIsMergeRoll());
            wmsOutReceiptMaterial.setInputBatchCode(o.getInputBatchCode());
            wmsOutReceiptMaterial.setMotherBatchCode(o.getMotherBatchCode());
            wmsOutReceiptMaterial.setPillar(o.getPillar());
            wmsOutReceiptMaterial.setMaterialDirection(o.getMaterialDirection());
            wmsOutReceiptMaterial.setStationNum(o.getStationNum());
            wmsOutReceiptMaterial.setProductModel(o.getSpecificationModel());
            wmsOutReceiptMaterial.setProductType(o.getProductType());
            wmsOutReceiptMaterial.setWmsOutReceiptTaskMaterialId(o.getId());
            return wmsOutReceiptMaterial;
        }).collect(Collectors.toList());

        //自动更新出库单节点
        WorkFlowInfoDto workFlowInfoDto = new WorkFlowInfoDto();
        workFlowInfoDto.setBusinessType("outbound_type");
        workFlowInfoDto.setDocumentType(receiptTask.getDocumentType());
        List<WmsFlowRecord> wmsFlowRecordList = workFlowService.workFlowInfo(workFlowInfoDto);
        if (!CollectionUtil.isEmpty(wmsFlowRecordList)) {
            WmsFlowRecord firstFlowRecord = CollectionUtil.getFirst(wmsFlowRecordList);
            BaseFlowDto firstFlowDto = new BaseFlowDto();
            firstFlowDto.setCode(firstFlowRecord.getFlowCode());
            firstFlowDto.setBusinessType("outbound_type");
            firstFlowDto.setDocumentType(receiptTask.getDocumentType());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("wmsOutReceipt",wmsOutReceipt);
            jsonObject.put("wmsOutReceiptMaterialList",wmsOutReceiptMaterialList);
            firstFlowDto.setData(jsonObject);
            workFlowService.commit( firstFlowDto);
        }
    }

//    /**
//     * 更新任务状态
//     */
//    public Boolean updateTaskMaterial(String receiptId) {
//        boolean taskOutFlag = true;
//        WmsOutReceipt wmsOutReceipt = wmsOutReceiptService.getById(receiptId);
//        if (Objects.isNull(wmsOutReceipt)) {
//            throw new JeecgBootException("出库单不存在!");
//        }
//        //出库任务id
//        String taskId = wmsOutReceipt.getWmsOutReceiptTaskId();
//        //出库任务-物料
//        List<WmsOutReceiptTaskMaterial> list = wmsOutReceiptTaskMaterialService.list(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
//                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, taskId));
//        if (ObjectUtil.isEmpty(list)) {
//            throw new JeecgBootException("出库任务无物料明细！");
//        }
//        WmsOutReceiptTask task = wmsOutReceiptTaskService.getById(taskId);
//        for (WmsOutReceiptTaskMaterial taskMaterial : list) {
//            LambdaQueryWrapper<WmsOutReceiptMaterial> tempQueryWrapper = new LambdaQueryWrapper<WmsOutReceiptMaterial>()
//                    .eq(WmsOutReceiptMaterial::getWmsOutReceiptId, wmsOutReceipt.getId())
//                    .eq(WmsOutReceiptMaterial::getWmsBasicMaterialId, taskMaterial.getWmsBasicMaterialId());
//            if (!StrUtil.isEmpty(taskMaterial.getBatchCode())) {
//                tempQueryWrapper.eq(WmsOutReceiptMaterial::getBatchCode, taskMaterial.getBatchCode());
//            }
//            List<WmsOutReceiptMaterial> realMaterialList = wmsOutReceiptMaterialService.list(tempQueryWrapper);
//            if (!CollectionUtil.isEmpty(realMaterialList)) {
//                //如果有这种物料，则比对任务数量和实际出库数量
//                WmsOutReceiptMaterial real = realMaterialList.get(0);
//                //获取未出库数量
//                BigDecimal unoutboundQuantity = taskMaterial.getUnoutboundQuantity();
//                if (ObjectUtil.isEmpty(unoutboundQuantity)) {
//                    //如果未出库数量为空，默认为计划出库数量
//                    unoutboundQuantity = taskMaterial.getPlanQuantity();
//                }
//                if (unoutboundQuantity.compareTo(real.getOutboundQuantity()) > 0) {
//                    taskOutFlag = false;
//                } else if (unoutboundQuantity.compareTo(real.getOutboundQuantity()) == 0) {
//                    taskOutFlag = true;
//                } else {
//                    taskOutFlag = true;
//                }
//            }
//        }
//        //重新获取更新过的出库任务-物料
//        List<WmsOutReceiptTaskMaterial> updatedList = wmsOutReceiptTaskMaterialService.list(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
//                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, taskId));
//        boolean anyMatch = updatedList.stream().anyMatch(o -> o.getUnoutboundQuantity().compareTo(BigDecimal.ZERO) != 0);
//        if(anyMatch) {
//            taskOutFlag=false;
//        }
//        if (!taskOutFlag) {
//            wmsOutReceiptTaskService.update(new LambdaUpdateWrapper<WmsOutReceiptTask>()
//                    .set(WmsOutReceiptTask::getOutboundStatus, OutboundStatusEnum.PART.getCode())
//                    .eq(WmsOutReceiptTask::getId,taskId)
//            );
//        }else {
//            wmsOutReceiptTaskService.update(new LambdaUpdateWrapper<WmsOutReceiptTask>()
//                    .set(WmsOutReceiptTask::getOutboundStatus,OutboundStatusEnum.ALL.getCode())
//                    .set(WmsOutReceiptTask::getDocumentStatus,DocumentStatusEnum.COMPLETE.getCode())
//                    .eq(WmsOutReceiptTask::getId,taskId)
//            );
//        }
//        return taskOutFlag;
//    }
}
